/*
 * Copyright (C) 2009 Jakub Miara
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.araim.rringtone;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeSet;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.ringdroid.SongMetadataReader;

public class BrowseForRingtones extends Activity {

	private ArrayList<RingtoneInfo> rings = new ArrayList<RingtoneInfo>();
	public static final String ADDED_RINGTONES = "ADDED_RINGTONES";
	public static final String CURRENT_FOLDER = "CURRENT_FOLDER";	
	private static final MusicFilter musicFilter = new MusicFilter();
	private int type;
	private String currentFolder = "/";

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			Intent i = new Intent();
			i.putExtra(ADDED_RINGTONES, rings.toArray(new RingtoneInfo[0]));
			setResult(RESULT_OK, i);
			finish();
		}
		return true;
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		try {
			setContentView(R.layout.ringtonesbrowser);
			
			if(savedInstanceState != null){
				currentFolder =savedInstanceState.getString(CURRENT_FOLDER);
				if (currentFolder==null || currentFolder.equals("")){
					currentFolder = "/";
				}
			}
			DisplayFolder(currentFolder);
			type = getIntent().getIntExtra(SelectRingtonesActivity.RINGTONE_TYPE, -1);
			if (type == -1) {
				return;
			}
			findViewById(R.id.ButtonBrowseDone).setOnClickListener(new OnClickListener() {
				public void onClick(View v) {
					Intent i = new Intent();
					i.putExtra(ADDED_RINGTONES, rings.toArray(new RingtoneInfo[0]));
					BrowseForRingtones.this.setResult(RESULT_OK, i);
					BrowseForRingtones.this.finish();
				}
			});

		} catch (Exception e) {
			Log.e(RandomRingtone.TAG, "Error initializing ringtone browser: " + e.toString());
		}

	}

	private void DisplayFolder(String string) {
		File f = new File(string);
		LinearLayout ll = (LinearLayout) findViewById(R.id.BrowseMainLayout);
		ll.removeAllViews();

		TextView tv = (TextView) findViewById(R.id.CurrentFolder);
		tv.setText("Current Folder: " + string);
		if (f.isDirectory()) {
			final FolderClickListener fcl = new FolderClickListener();
			FileClickListener filecl = new FileClickListener();
			View v = LayoutInflater.from(getApplicationContext()).inflate(R.layout.browserelementlayout, null);
			LinearLayout inner = (LinearLayout) v;
			ImageView iv = (ImageView) inner.getChildAt(0);
			iv.setImageResource(R.drawable.folder_up);
			ImageChangeTouchListener ictl = new ImageChangeTouchListener(iv, R.drawable.folder_up, R.drawable.folder_up_brown);
			iv.setOnTouchListener(ictl);
			tv = (TextView) inner.getChildAt(1);

			tv.setText("Parent directory");
			inner.setTag(f.getParentFile() != null ? f.getParentFile() : f);
			inner.setOnTouchListener(ictl);
			inner.setOnClickListener(fcl);
			ll.addView(v);
			LinearLayout line = new LinearLayout(getApplicationContext());
			line.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 1));
			line.setFadingEdgeLength(20);
			line.setBackgroundColor(0xff999999);
			ll.addView(line);
			File[] files = f.listFiles(musicFilter);
			if (files != null) {
				TreeSet<File> ts = new TreeSet<File>(new Comparator<File>() {

					public int compare(File object1, File object2) {
						if ((object1.isDirectory() && object2.isDirectory()) || (!object1.isDirectory() && !object2.isDirectory())) {
							return object1.getName().compareTo(object2.getName());
						} else if (!object1.isDirectory() && object2.isDirectory()) {
							return 1;
						} else {
							return -1;
						}
					}
				});
				for (File fil : files) {
					ts.add(fil);
				}

				for (File file : ts) {
					v = LayoutInflater.from(getApplicationContext()).inflate(R.layout.browserelementlayout, null);
					inner = (LinearLayout) v;
					iv = (ImageView) inner.getChildAt(0);
					tv = (TextView) inner.getChildAt(1);
					tv.setText(file.getName());

					if (file.isDirectory()) {
						iv.setImageResource(R.drawable.folder);
						ictl = new ImageChangeTouchListener(iv, R.drawable.folder, R.drawable.folderbrown);
						iv.setOnTouchListener(ictl);
						inner.setOnTouchListener(ictl);
						inner.setOnClickListener(fcl);
					} else {
						iv.setImageResource(R.drawable.musicfileicon);
						inner.setOnClickListener(filecl);
					}

					inner.setTag(file);
					ll.addView(v);
				}
			}
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putString(CURRENT_FOLDER, currentFolder);
	}

	private class ImageChangeTouchListener implements OnTouchListener {

		private int from;
		private int to;
		private ImageView iv;

		public ImageChangeTouchListener(ImageView v, int from, int to) {
			this.iv = v;
			this.from = from;
			this.to = to;
		}

		public boolean onTouch(View v, MotionEvent event) {
			if (event.getAction() == MotionEvent.ACTION_DOWN) {
				iv.setImageResource(to);
			} else if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_OUTSIDE
					|| event.getAction() == MotionEvent.ACTION_CANCEL) {
				iv.setImageResource(from);
			}
			return false;
		}

	}

	private class FolderClickListener implements OnClickListener {
		public void onClick(View v) {
			File f = (File) v.getTag();
			currentFolder = f.getAbsolutePath();
			DisplayFolder(currentFolder);
		}
	}
	
	private class FileClickListener implements OnClickListener {
		public void onClick(View v) {
			final ImageView iv = (ImageView) ((LinearLayout) v).getChildAt(0);
			iv.setImageResource(R.drawable.musicfileicon_add);
			final File f = (File) v.getTag();
			final String typeName = RingtoneInfo.getRingtoneTypeName(type);
			new AlertDialog.Builder(BrowseForRingtones.this).setTitle("Add " + typeName).setMessage("Add this file as a " + typeName + "?")
					.setPositiveButton("Yes", new DialogInterface.OnClickListener() {

						public void onClick(DialogInterface dialog, int which) {
							Log.d(RandomRingtone.TAG, "Adding the " + typeName);
							try {
								String path = f.getAbsolutePath();

								SongMetadataReader metadataReader = new SongMetadataReader(BrowseForRingtones.this, path);
								String title = metadataReader.mTitle;
								String artist = metadataReader.mArtist;
								String album = metadataReader.mAlbum;
								int year = metadataReader.mYear;
								int id = metadataReader.mId;

								if (title == null || title.trim().equals("")) {
									title = f.getName();
								}

								if (id < 1) {
									try {
										boolean ringtone = (type == RingtoneManager.TYPE_RINGTONE);
										boolean notification = (type == RingtoneManager.TYPE_NOTIFICATION);
										boolean alarm = (type == RingtoneManager.TYPE_ALARM);
										Uri u = RingtoneInfo.insertRingtone(getContentResolver(), path, title, artist, album, year,
												ringtone, notification,alarm);
										RingtoneInfo ri = new RingtoneInfo();
										ri.setName(title);
										ri.setId(Integer.parseInt(u.getLastPathSegment()));
										ri.setUri(u.toString().substring(0, u.toString().length() - (u.getLastPathSegment().length() + 1)));
										ri.setRtype(type);
										rings.add(ri);
										Toast.makeText(getApplicationContext(), String.format(typeName + " \"%s\" added.", title), 1000)
												.show();
									} catch (Exception e) {
										Log.w(RandomRingtone.TAG, "Cannot add " + typeName + " or read it's URI : " + e.toString());
									}
								} else {
									Uri uri = MediaStore.Audio.Media.getContentUriForPath(path);
									RingtoneInfo.enable(getContentResolver(), uri, id, type);
									Uri ringtoneUri = Uri.parse(uri.toString() + "/" + id);

									Uri curr = RingtoneManager.getActualDefaultRingtoneUri(getApplicationContext(),
											RingtoneManager.TYPE_RINGTONE);
									RingtoneManager.setActualDefaultRingtoneUri(getApplicationContext(), type, ringtoneUri);
									RingtoneManager.setActualDefaultRingtoneUri(getApplicationContext(), type, curr);

									RingtoneInfo ri = new RingtoneInfo();
									ri.setUri(uri.toString());
									ri.setId(id);
									ri.setName(title);
									ri.setRtype(type);
									rings.add(ri);
									Toast.makeText(getApplicationContext(), String.format(typeName + " \"%s\" added.", title), 1000).show();
								}
							} catch (Exception e) {
								Log.e(RandomRingtone.TAG, "Error adding the ringtone: " + e.toString());
							} finally {
								iv.setImageResource(R.drawable.musicfileicon);
							}
						}
					}).setNegativeButton("No", new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							iv.setImageResource(R.drawable.musicfileicon);
						}
					}).show();
		}
	}

	private static class MusicFilter implements FileFilter {
		public boolean accept(File pathname) {
			if (pathname.isDirectory()) {
				return true;
			}
			String fileName = pathname.getName();
			if (fileName.endsWith(".mp3") || fileName.endsWith(".3gp") || fileName.endsWith(".mid") || fileName.endsWith(".ogg")
					|| fileName.endsWith(".wav") || fileName.endsWith(".xmf") || fileName.endsWith(".mp4") || fileName.endsWith(".m4a")
					|| fileName.endsWith(".mxmf") || fileName.endsWith(".rtttl") || fileName.endsWith(".rtx") || fileName.endsWith(".ota")
					|| fileName.endsWith(".imy")) {
				return true;
			} else {
				return false;
			}
		}

	}
}
